#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

struct edge
{
	int to, c, was;

	edge(int to = 0, int c = 0) : to(to), c(c) {was = c;}
};

edge ed[40005];
int sze = 0;
vector<int> g[54];

void AddE(int v, int to, int c)
{
	g[v].push_back(sze);
	ed[sze ++] = edge(to, c);
	g[to].push_back(sze);
	ed[sze ++] = edge(v, c);
}

bool u[54];
int d[54];

bool bfs(int st, int fin)
{
	memset(u, 0, sizeof(u));
	queue<int> q;
	q.push(st);
	u[st] = 1;
	d[st] = 0;
	while(q.size() > 0)
	{
		int v = q.front(); q.pop();
		for(int i = 0; i < g[v].size(); i++)
		{
			int id = g[v][i];
			if(!u[ed[id].to] && ed[id].c > 0)
			{
				q.push(ed[id].to);
				u[ed[id].to] = 1;
				d[ed[id].to] = d[v] +1;
			}
		}
	}
	return u[fin];
}

int ptr[54];
int inf = 1000000000;

int dfs(int v, int fin, int flow)
{
	if(v == fin)
		return flow;
	for(int i = ptr[v]; i < g[v].size(); i++)
	{
		int id = g[v][i];
		if(d[ed[id].to] == d[v] + 1 && ed[id].c > 0)
		{
			int fl = dfs(ed[id].to, fin, min(flow, ed[id].c));
			if(fl > 0)
			{
				ed[id].c -= flow;
				ed[id^1].c += flow;
				return fl;
			}
		}
		ptr[v] ++;
	}
	return 0;
}

int getFlow(int st, int fin)
{
	int flow = 0;
	while(bfs(st, fin))
	{
		memset(ptr, 0, sizeof(ptr));
		while(1)
		{
			int add = dfs(st, fin, inf);
			if(add == 0)
				break;
			flow += add;
		}
	}
	return flow;
}

int a[55][55];

pair<pair<int, int>, int> ans[55 * 55];
int sza = 0;
vector<pair<int, pair<int, int> > > pr;


int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < n;j ++) {
			scanf("%d", &a[i][j]); 
			if(i < j)
				pr.push_back( make_pair(a[i][j], make_pair(i, j)));
		}
	}
	sort(pr.begin(), pr.end());
	reverse(pr.begin(), pr.end());

	for(int t = 0; t < pr.size(); t++)
	{
		int i = pr[t].second.first, j = pr[t].second.second;
		for(int k = 0; k < sze; k++)
			ed[k].c = ed[k].was;
		int fl = getFlow(i, j);
		if(fl > a[i][j])
		{
			printf("NO\n");
			return 0;
		}
		if(a[i][j] > fl)
			AddE(i, j, a[i][j] - fl), ans[sza ++] = make_pair(make_pair(i, j), a[i][j] - fl);
	}

	for(int i = 0; i < n; i++)
	{
		for(int j = i + 1; j < n; j++)
		{
			for(int k = 0; k < sze; k++)
				ed[k].c = ed[k].was;
			int fl = getFlow(i, j);
			if(fl != a[i][j])
			{
				printf("NO\n");
				return 0;
			}
		}
	}
	printf("YES\n");
	printf("%d\n", sza);
	for(int i = 0; i < sza; i++)
		printf("%d %d %d\n", ans[i].first.first + 1, 1+ ans[i].first.second, ans[i].second);



	return 0;
}